package com.fangyi.yunmusic.config;

import com.fangyi.yunmusic.exception.CacheEmptyException;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Configuration
public class UserTokenConfig {

    public static final String USER_TOKEN = "user-token";

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private LoadingCache<String, String> userTokenCache;

    // token缓存：userId -> userToken
    @Bean("userTokenCache")
    public LoadingCache<String, String> UserTokenCache() {
        LoadingCache<String, String> userTokenCache = CacheBuilder.newBuilder()
                .initialCapacity(0)    // 设置缓存容器的初始容量为0
                .maximumSize(100)       // 设置缓存容器的最大容量为100，超过100之后就会按照LRU最近最少使用算法来移除缓存项
                .expireAfterWrite(7, TimeUnit.DAYS)     // 设置缓存一周后过期
                .build(new CacheLoader<String, String>() {      // 生成 缓存值 的方法
                    @Override
                    public String load(String userId) throws Exception {
                        String userToken = getUserTokenFormRedis(userId);

                        if (userToken == null) {
                            throw new CacheEmptyException("not cache");
                        }

                        return userToken;

//                        // 生成随机串，表示userToken
//                        userToken = UUID.randomUUID().toString();
//                        // 保存到Redis
//                        setUserTokenToRedis(userId, userToken);

                    }
                });

        return userTokenCache;
    }

    public String setUserToken(String userId) {
        String userToken = UUID.randomUUID().toString();
        setUserTokenToRedis(userId, userToken);
        userTokenCache.put(userId, userToken);
        return userToken;
    }

    public void removeUserToken(String userId) {
        redisTemplate.delete(userId);
        userTokenCache.invalidate(userId);
    }

    private String getUserTokenFormRedis(String userId) {
        String key = convertToKey(userId);
        return redisTemplate.opsForValue().get(key);
    }

    private void setUserTokenToRedis(String userId, String userToken) {
        String key = convertToKey(userId);
        redisTemplate.opsForValue().set(key, userToken, 7, TimeUnit.DAYS);
    }

    private String convertToKey(String userId) {
        return USER_TOKEN + ":" + userId;
    }

}
